package com.zhihaoliang.moshi.biz.adapter

import com.squareup.moshi.*
import com.zhihaoliang.moshi.biz.adapter.DefaultOnDataMismatchAdapter.Companion.newFactory
import com.zhihaoliang.moshi.biz.models.Suit
import com.zhihaoliang.moshi.util.log
import java.lang.reflect.Type


/**
 * @author 支豪亮
 * @date 2023/1/28 17:19
 * @des 当不是正常值时，选择默认值
 */

class DefaultOnDataMismatchAdapter<T> private constructor(private val delegate: JsonAdapter<T>, private val defaultValue: T) :
    JsonAdapter<T>() {
    override fun fromJson(reader: JsonReader): T? {
        val peeked = reader.peekJson()
        return try {
            delegate.fromJson(peeked)
        } catch (e: Exception) {
            defaultValue
        } finally {
            peeked.close()

            // Skip the value back on the reader, no matter the state of the peeked reader.
            reader.skipValue()
        }
    }

    override fun toJson(writer: JsonWriter, value: T?) {
        delegate.toJson(writer, value)
    }

    companion object{
        fun <T>newFactory(type:Class<T>,defaultValue: T): Factory =object :Factory{
            override fun create(
                requestedType: Type, annotations: MutableSet<out Annotation>, moshi: Moshi
            ): JsonAdapter<T>? {
                if (type != requestedType) return null
                val delegate: JsonAdapter<T> = moshi.nextAdapter(this, type, annotations)
                return DefaultOnDataMismatchAdapter(delegate, defaultValue)
            }

        }
    }
}

fun recoverFromTypeMismatch() {
    // 只接收 CLUBS(梅花) ,DIAMONDS(方块),HEARTS(红桃), SPADES(黑桃) 所以 STARS 自动转化为 Suit.CLUBS
    val json = """
        ["DIAMONDS", "STARS", "HEARTS"]
    """.trimIndent()

    val moshi =
        Moshi.Builder().add(newFactory(Suit::class.java, Suit.CLUBS))
            .build()
    val jsonAdapter: JsonAdapter<List<Suit>> = moshi.adapter(
        Types.newParameterizedType(
            MutableList::class.java, Suit::class.java
        )
    )

    log(jsonAdapter.fromJson(json).toString())
}